﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;
using VBOX.Properties;

namespace VBOX
{
    public partial class VBOX : Form
    {
        public string selectPath;
        public string savePath;
        
        private int TimerHexRecvCount = 0;
        private string send_history_path = "F:/vbox_send_history.info";
        private VboxSerialPort serial = null;
        private bool BtnOpenFlag = false; //按钮开关记录
        private VboxSocket socket = null;

        public VBOX()
        {
            InitializeComponent();
            richText_sp.MouseWheel += new MouseEventHandler(richText_sp_MouseWheel);
        }

        #region 主窗体加载/关闭
        private void VBOX_Load(object sender, EventArgs e)
        {
            //初始化状态栏收发数据量
            UpdateTxRxState();
            //获取当前所有串口名称并记录
            VboxSerialPort.SetPortNameValues(CbxSpName);
            //添加配置项
            VboxSerialPort.SetBauRateValues(CbxBaudRate);
            VboxSerialPort.SetDataBitValues(CbxDataBit);
            VboxSerialPort.SetStopBitValues(CbxStopBit);
            VboxSerialPort.SetParityValues(CbxCheckBit);

            //默认选页1
            radioButtonPage1.Checked = true;
            //获取上次配置信息
            GetAllSerialPortSettings();

            //使用字符串参数构造
            serial = new VboxSerialPort();
            //添加委托
            serial.updateTextBox = new VboxSerialPort.UpdateTextEventHandler(UpdateSpTextBox); //sp recv 3

            //如果上次使用的串口在 当前串口列表中 则打开该串口
            for (int i = 0; i < CbxSpName.Items.Count; i++)
            {
                if (string.Compare(CbxSpName.GetItemText(CbxSpName.Items[i]), CbxSpName.Text) == 0)
                {
                    //打开串口
                    SerialPortOpen();
                }
            }
        }

        private void VBOX_FormClosing(object sender, FormClosingEventArgs e)
        {
            //进入关闭流程
            if (CheckBoxSaveToFile.Checked == true)
            {
                VboxSerialPort.flag_close = true;
                if (MessageBox.Show("正在使用 【扩展功能 -> 自动保存】, 是否确认退出？","提示", MessageBoxButtons.OKCancel,
                MessageBoxIcon.Question) == DialogResult.OK)
                {
                    //如果确定关闭则保存相关配置
                    SerialPortClose();
                    SaveAllSerialPortSettings();
                }
                else 
                {
                    //如果不关闭则退出关闭流程
                    VboxSerialPort.flag_close = false;
                    e.Cancel = true;
                }
                return;
            }

            VboxSerialPort.flag_close = true;
            if (MessageBox.Show("是否确认退出？", "提示", MessageBoxButtons.OKCancel,
                MessageBoxIcon.Question) == DialogResult.OK)
            {
                //如果确定关闭则保存相关配置
                SerialPortClose();
                SaveAllSerialPortSettings();
            }
            else
            {
                //如果不关闭则退出关闭流程
                VboxSerialPort.flag_close = false;
                e.Cancel = true;
            }
            return;
        }
        #endregion

        #region 串口设置保存
        //获取上次关闭前的配置数据
        private void GetAllSerialPortSettings()
        {
            CbxSpName.Text = Settings.Default.PortName;
            CbxBaudRate.Text = Settings.Default.BaudRate;
            CbxStopBit.Text = Settings.Default.StopBit;
            CbxDataBit.Text = Settings.Default.DataBit;
            CbxCheckBit.Text = Settings.Default.CheckBit;
            CheckBoxNewLine.Checked = Settings.Default.NewLine;
            CheckBoxHexSend.Checked = Settings.Default.HexSend;
            CheckBoxShowTime.Checked = Settings.Default.ShowTime;
            if (CbxBaudRate.Text == "")
                CbxBaudRate.Text = "115200";
            if (CbxStopBit.Text == "")
                CbxStopBit.Text = "1";
            if (CbxDataBit.Text == "")
                CbxDataBit.Text = "8";
            if (CbxCheckBit.Text == "")
                CbxCheckBit.Text = "无";

            //初始化页1的内容
            TbxMultiSend1.Text = Settings.Default.TbxMultiSendP11;
            TbxMultiSend2.Text = Settings.Default.TbxMultiSendP12;
            TbxMultiSend3.Text = Settings.Default.TbxMultiSendP13;
            TbxMultiSend4.Text = Settings.Default.TbxMultiSendP14;
            TbxMultiSend5.Text = Settings.Default.TbxMultiSendP15;
            TbxMultiSend6.Text = Settings.Default.TbxMultiSendP16;
            TbxMultiSend7.Text = Settings.Default.TbxMultiSendP17;
            TbxMultiSend8.Text = Settings.Default.TbxMultiSendP18;
        }

        //保存当前配置数据
        private void SaveAllSerialPortSettings()
        {
            Settings.Default.PortName = CbxSpName.Text;
            Settings.Default.BaudRate = CbxBaudRate.Text;
            Settings.Default.StopBit = CbxStopBit.Text;
            Settings.Default.DataBit = CbxDataBit.Text;
            Settings.Default.CheckBit = CbxCheckBit.Text;
            Settings.Default.NewLine = CheckBoxNewLine.Checked;
            Settings.Default.HexSend = CheckBoxHexSend.Checked;
            Settings.Default.ShowTime = CheckBoxShowTime.Checked;

            Settings.Default.Save();
        }

        #endregion

        #region 串口打开/关闭

        private void SerialPortOpen()
        {
            bool result = false;

            //开启串口
            if (CbxSpName.Text == "TCP/IP...")
            {
                if (socket != null)
                    result = socket.Open(CbxCheckBit, CbxBaudRate);
            }
            else
            {
                if (serial != null)
                    result = serial.OpenPort(CbxSpName.Text, CbxBaudRate.Text, CbxDataBit.Text, CbxStopBit.Text, CbxCheckBit.Text);
            }
                
            if (result == true)
            {
                BtnOpenFlag = true;

                //显示提示文字
                BtnSpOpenAndClose.Text = "关闭串口";
                LabelSpState.Text = "串口已打开";
            }

        }

        private void SerialPortClose()
        {
            bool result = false;

            //关闭串口
            if (CbxSpName.Text == "TCP/IP...")
            {
                if (socket != null)
                    result = socket.Close(CbxBaudRate);
            }
            else
            {
                if (serial != null)
                    result = serial.ClosePort();
            }
                
            if (result == true)
            {
                BtnOpenFlag = false;

                //显示提示文字
                BtnSpOpenAndClose.Text = "打开串口";
                LabelSpState.Text = "串口已关闭";
            }
        }

        private void CbxBaudRate_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (CbxBaudRate.Text != "custom")
                CbxBaudRate.DropDownStyle = ComboBoxStyle.DropDownList;
            else
                CbxBaudRate.DropDownStyle = ComboBoxStyle.DropDown;
        }

        private void BtnSpOpenAndClose_Click(object sender, EventArgs e)
        {
            if (BtnOpenFlag == true)
            {
                if (CbxSpName.Text == "TCP/IP...")
                {
                    //关闭串口
                    SerialPortClose();
                    socket = null;
                }
                else 
                {
                    VboxSerialPort.SpClosing = true;
                    while (VboxSerialPort.Listening) Application.DoEvents();
                    //关闭串口
                    SerialPortClose();
                    VboxSerialPort.SpClosing = false;
                }
            }
            else
            {
                if (CbxSpName.Text == "TCP/IP...")
                {
                    if (CbxBaudRate.Text == "")
                    {
                        MessageBox.Show("请选择模式");
                        return;
                    }
                    if (CbxBaudRate.Text == "tcp_client")
                    {
                        if ((CbxStopBit.Text == "") || 
                            (CbxDataBit.Text == ""))
                        {
                            MessageBox.Show("请输入IP/端口");
                            return;
                        }
                    }
                    socket = new VboxSocket(CbxStopBit.Text, CbxDataBit.Text);
                    //添加委托
                    socket.updateTextBox = new VboxSocket.UpdateTextEventHandler(UpdateSpTextBox);
                    //打开串口
                    SerialPortOpen();
                }
                else 
                {
                    //打开串口
                    SerialPortOpen();
                }
            }
        }

        private void CbxSpName_Click(object sender, EventArgs e)
        {
            SerialPortClose();
            VboxSerialPort.SetPortNameValues(CbxSpName);
            CbxSpName.Items.Add("TCP/IP...");
        }

        #endregion

        #region 串口接收显示

        /// <summary>
        /// 子线程更新UI 串口接收到的数据显示到TextBox中
        /// </summary>
        /// <param name="recData"></param>
        private void UpdateSpTextBox(byte[] recData)
        {
            //Invoke(updateText, recData); //sp recv 4 使用BeginInvoke避免锁死
            BeginInvoke(new Action(() =>
            {
                updateText(recData);
            }));
        }

        //显示数据到串口显示区
        private void updateText(byte[] recData) //sp recv 5
        {
            UpdateTxRxState();

            //16进制显示
            if (CheckBoxHexShow.Checked == true)
            {
                byte[] showData = recData;

                //有16进制数据 开启定时器 并显示当前时间
                if (TimerHexRecv.Enabled != true)
                {
                    TimerHexRecv.Start();
                    string print_time = DateTime.Now.ToString("HH:mm:ss.fff");
                    SaveToFileOrTextbox("[" + print_time + "] <- ");
                }

                //清零累加计数变量
                TimerHexRecvCount = 0;

                //打印接收到的16进制数据
                foreach (byte str in showData)
                {
                    SaveToFileOrTextbox(string.Format("{0:X2} ", str));
                }
            }
            else //字符串显示
            {
                string showText = Encoding.Default.GetString(recData);
                
                if (CheckBoxShowTime.Checked == true)  //添加时间戳
                {
                    string print_time = DateTime.Now.ToString("HH:mm:ss.fff");
                    //替换掉错误的回车换行 防止在rich_text_box中不换行显示的问题
                    string print_temp = showText.Replace("\r\r\n", "\r\n");
                    string print_str = print_temp.Replace("\r\n", "\r\n" + "[" + print_time + "] ");

                    SaveToFileOrTextbox(print_str);
                }
                else
                {
                    SaveToFileOrTextbox(showText);
                }
            }

        }
        #endregion

        #region 串口发送基本功能
        private void SerialPortSendData(string data)
        {
            //发送回车换行
            if (CheckBoxNewLine.Checked == true)
            {
                if (CheckBoxHexSend.Checked == true)
                {
                    if (CbxSpName.Text == "TCP/IP...")
                    {
                        if (socket != null)
                            socket.SendDataByHex(CbxBaudRate, data + " 0D 0A");
                    }
                    else
                    {
                        if (serial != null)
                            serial.SendDataByHex(data + " 0D 0A");
                    }
                }
                else
                {
                    if (CbxSpName.Text == "TCP/IP...")
                    {
                        if (socket != null)
                            socket.SendDataByString(CbxBaudRate, data + "\r\n");
                    }
                    else
                    {
                        if (serial != null)
                            serial.SendDataByString(data + "\r\n");
                    }
                    
                }
            }
            else
            {
                if (CheckBoxHexSend.Checked == true)
                {
                    if (CbxSpName.Text == "TCP/IP...")
                    {
                        if (socket != null)
                            socket.SendDataByHex(CbxBaudRate, data);
                    }
                    else
                    {
                        if (serial != null)
                            serial.SendDataByHex(data);
                    }
                }
                else
                {
                    if (CbxSpName.Text == "TCP/IP...")
                    {
                        if (socket != null)
                            socket.SendDataByString(CbxBaudRate, data);
                    }
                    else
                    {
                        if (serial != null)
                            serial.SendDataByString(data);
                    }
                }
            }
        }
        #endregion

        #region 串口单条发送
        private void BtnSingleSend_Click(object sender, EventArgs e)
        {
            //发送数据
            SerialPortSendData(TbxSingleSend.Text);
            richText_sp.Focus();

            //保存数据到历史记录
            if (File.Exists(send_history_path) == true)
            {
                string[] history = File.ReadAllLines(send_history_path);
                for (int i = 0; i < history.Length; i++)
                {
                    if (string.Compare(history[i], TbxSingleSend.Text) == 0)
                    {
                        return; //如果历史文件存在 则不保存
                    }
                }

                //如果历史条数大于50 则删除时间最远的一条
                if (history.Length >= 50)
                {
                    List<string> his_list = history.ToList();
                    his_list.RemoveAt(0);
                    File.WriteAllLines(send_history_path, his_list.ToArray());
                }
            }

            //如果历史文件不存在 则保存
            System.IO.File.AppendAllText(send_history_path, TbxSingleSend.Text+"\r\n");
        }
        #endregion

        #region 串口多条发送
        private void BtnMultiSend1_Click(object sender, EventArgs e)
        {
            SerialPortSendData(TbxMultiSend1.Text);
            richText_sp.Focus();
        }

        private void BtnMultiSend2_Click(object sender, EventArgs e)
        {
            SerialPortSendData(TbxMultiSend2.Text);
            richText_sp.Focus();
        }

        private void BtnMultiSend3_Click(object sender, EventArgs e)
        {
            SerialPortSendData(TbxMultiSend3.Text);
            richText_sp.Focus();
        }

        private void BtnMultiSend4_Click(object sender, EventArgs e)
        {
            SerialPortSendData(TbxMultiSend4.Text);
            richText_sp.Focus();
        }

        private void BtnMultiSend5_Click(object sender, EventArgs e)
        {
            SerialPortSendData(TbxMultiSend5.Text);
            richText_sp.Focus();
        }

        private void BtnMultiSend6_Click(object sender, EventArgs e)
        {
            SerialPortSendData(TbxMultiSend6.Text);
            richText_sp.Focus();
        }

        private void BtnMultiSend7_Click(object sender, EventArgs e)
        {
            SerialPortSendData(TbxMultiSend7.Text);
            richText_sp.Focus();
        }

        private void BtnMultiSend8_Click(object sender, EventArgs e)
        {
            SerialPortSendData(TbxMultiSend8.Text);
            richText_sp.Focus();
        }

        #endregion

        #region 多条发送内容保存
        private void TbxMultiSend1_TextChanged(object sender, EventArgs e)
        {
            if (radioButtonPage1.Checked == true)
            {
                Settings.Default.TbxMultiSendP11 = TbxMultiSend1.Text;
            }
            else if (radioButtonPage2.Checked == true)
            {
                Settings.Default.TbxMultiSendP21 = TbxMultiSend1.Text;
            }
            else if (radioButtonPage3.Checked == true)
            {
                Settings.Default.TbxMultiSendP31 = TbxMultiSend1.Text;
            }
        }

        private void TbxMultiSend2_TextChanged(object sender, EventArgs e)
        {
            if (radioButtonPage1.Checked == true)
            {
                Settings.Default.TbxMultiSendP12 = TbxMultiSend2.Text;
            }
            else if (radioButtonPage2.Checked == true)
            {
                Settings.Default.TbxMultiSendP22 = TbxMultiSend2.Text;
            }
            else if (radioButtonPage3.Checked == true)
            {
                Settings.Default.TbxMultiSendP32 = TbxMultiSend2.Text;
            }
        }

        private void TbxMultiSend3_TextChanged(object sender, EventArgs e)
        {
            if (radioButtonPage1.Checked == true)
            {
                Settings.Default.TbxMultiSendP13 = TbxMultiSend3.Text;
            }
            else if (radioButtonPage2.Checked == true)
            {
                Settings.Default.TbxMultiSendP23 = TbxMultiSend3.Text;
            }
            else if (radioButtonPage3.Checked == true)
            {
                Settings.Default.TbxMultiSendP33 = TbxMultiSend3.Text;
            }
        }

        private void TbxMultiSend4_TextChanged(object sender, EventArgs e)
        {
            if (radioButtonPage1.Checked == true)
            {
                Settings.Default.TbxMultiSendP14 = TbxMultiSend4.Text;
            }
            else if (radioButtonPage2.Checked == true)
            {
                Settings.Default.TbxMultiSendP24 = TbxMultiSend4.Text;
            }
            else if (radioButtonPage3.Checked == true)
            {
                Settings.Default.TbxMultiSendP34 = TbxMultiSend4.Text;
            }
        }

        private void TbxMultiSend5_TextChanged(object sender, EventArgs e)
        {
            if (radioButtonPage1.Checked == true)
            {
                Settings.Default.TbxMultiSendP15 = TbxMultiSend5.Text;
            }
            else if (radioButtonPage2.Checked == true)
            {
                Settings.Default.TbxMultiSendP25 = TbxMultiSend5.Text;
            }
            else if (radioButtonPage3.Checked == true)
            {
                Settings.Default.TbxMultiSendP35 = TbxMultiSend5.Text;
            }
        }

        private void TbxMultiSend6_TextChanged(object sender, EventArgs e)
        {
            if (radioButtonPage1.Checked == true)
            {
                Settings.Default.TbxMultiSendP16 = TbxMultiSend6.Text;
            }
            else if (radioButtonPage2.Checked == true)
            {
                Settings.Default.TbxMultiSendP26 = TbxMultiSend6.Text;
            }
            else if (radioButtonPage3.Checked == true)
            {
                Settings.Default.TbxMultiSendP36 = TbxMultiSend6.Text;
            }
        }

        private void TbxMultiSend7_TextChanged(object sender, EventArgs e)
        {
            if (radioButtonPage1.Checked == true)
            {
                Settings.Default.TbxMultiSendP17 = TbxMultiSend7.Text;
            }
            else if (radioButtonPage2.Checked == true)
            {
                Settings.Default.TbxMultiSendP27 = TbxMultiSend7.Text;
            }
            else if (radioButtonPage3.Checked == true)
            {
                Settings.Default.TbxMultiSendP37 = TbxMultiSend7.Text;
            }
        }

        private void TbxMultiSend8_TextChanged(object sender, EventArgs e)
        {
            if (radioButtonPage1.Checked == true)
            {
                Settings.Default.TbxMultiSendP18 = TbxMultiSend8.Text;
            }
            else if (radioButtonPage2.Checked == true)
            {
                Settings.Default.TbxMultiSendP28 = TbxMultiSend8.Text;
            }
            else if (radioButtonPage3.Checked == true)
            {
                Settings.Default.TbxMultiSendP38 = TbxMultiSend8.Text;
            }
        }

        private void radioButtonPage1_CheckedChanged(object sender, EventArgs e)
        {
            TbxMultiSend1.Text = Settings.Default.TbxMultiSendP11;
            TbxMultiSend2.Text = Settings.Default.TbxMultiSendP12;
            TbxMultiSend3.Text = Settings.Default.TbxMultiSendP13;
            TbxMultiSend4.Text = Settings.Default.TbxMultiSendP14;
            TbxMultiSend5.Text = Settings.Default.TbxMultiSendP15;
            TbxMultiSend6.Text = Settings.Default.TbxMultiSendP16;
            TbxMultiSend7.Text = Settings.Default.TbxMultiSendP17;
            TbxMultiSend8.Text = Settings.Default.TbxMultiSendP18;
        }

        private void radioButtonPage2_CheckedChanged(object sender, EventArgs e)
        {
            TbxMultiSend1.Text = Settings.Default.TbxMultiSendP21;
            TbxMultiSend2.Text = Settings.Default.TbxMultiSendP22;
            TbxMultiSend3.Text = Settings.Default.TbxMultiSendP23;
            TbxMultiSend4.Text = Settings.Default.TbxMultiSendP24;
            TbxMultiSend5.Text = Settings.Default.TbxMultiSendP25;
            TbxMultiSend6.Text = Settings.Default.TbxMultiSendP26;
            TbxMultiSend7.Text = Settings.Default.TbxMultiSendP27;
            TbxMultiSend8.Text = Settings.Default.TbxMultiSendP28;
        }

        private void radioButtonPage3_CheckedChanged(object sender, EventArgs e)
        {
            TbxMultiSend1.Text = Settings.Default.TbxMultiSendP31;
            TbxMultiSend2.Text = Settings.Default.TbxMultiSendP32;
            TbxMultiSend3.Text = Settings.Default.TbxMultiSendP33;
            TbxMultiSend4.Text = Settings.Default.TbxMultiSendP34;
            TbxMultiSend5.Text = Settings.Default.TbxMultiSendP35;
            TbxMultiSend6.Text = Settings.Default.TbxMultiSendP36;
            TbxMultiSend7.Text = Settings.Default.TbxMultiSendP37;
            TbxMultiSend8.Text = Settings.Default.TbxMultiSendP38;
        }

        #endregion

        #region 循环发送
        private int[] flagTimerSend = new int[10];
        private void TimerLoopSend_Tick(object sender, EventArgs e)
        {
            if (serial == null)
            {
                return;
            }

            if (checkBoxLoopSend.Checked == true)
            {
                if ((checkBoxMultiSend1.Checked == true) && (flagTimerSend[0] == 0))
                {
                    SerialPortSendData(TbxMultiSend1.Text);
                    flagTimerSend[0] = 1;
                    return;
                }

                if ((checkBoxMultiSend2.Checked == true) && (flagTimerSend[1] == 0))
                {
                    SerialPortSendData(TbxMultiSend2.Text);
                    flagTimerSend[1] = 1;
                    return;
                }
                if ((checkBoxMultiSend3.Checked == true) && (flagTimerSend[2] == 0))
                {
                    SerialPortSendData(TbxMultiSend3.Text);
                    flagTimerSend[2] = 1;
                    return;
                }
                if ((checkBoxMultiSend4.Checked == true) && (flagTimerSend[3] == 0))
                {
                    SerialPortSendData(TbxMultiSend4.Text);
                    flagTimerSend[3] = 1;
                    return;
                }
                if ((checkBoxMultiSend5.Checked == true) && (flagTimerSend[4] == 0))
                {
                    SerialPortSendData(TbxMultiSend5.Text);
                    flagTimerSend[4] = 1;
                    return;
                }
                if ((checkBoxMultiSend6.Checked == true) && (flagTimerSend[5] == 0))
                {
                    SerialPortSendData(TbxMultiSend6.Text);
                    flagTimerSend[5] = 1;
                    return;
                }
                if ((checkBoxMultiSend7.Checked == true) && (flagTimerSend[6] == 0))
                {
                    SerialPortSendData(TbxMultiSend7.Text);
                    flagTimerSend[6] = 1;
                    return;
                }
                if ((checkBoxMultiSend8.Checked == true) && (flagTimerSend[7] == 0))
                {
                    SerialPortSendData(TbxMultiSend8.Text);
                    flagTimerSend[7] = 1;
                    return;
                }

                for (int i = 0; i < 8; i++)
                    flagTimerSend[i] = 0;
            }
        }

        private void checkBoxLoopSend_CheckedChanged(object sender, EventArgs e)
        {
            if (serial != null)
            {
                if (checkBoxLoopSend.Checked == true)
                {
                    if (TbxLoopSendTime.Text != "")
                    {
                        TbxLoopSendTime.ReadOnly = true;
                        TimerLoopSend.Interval = Convert.ToInt32(TbxLoopSendTime.Text);
                        TimerLoopSend.Start();
                    }
                    else
                    {
                        checkBoxLoopSend.Checked = false;
                        MessageBox.Show("请设置间隔时间");
                    }
                }
                else
                {
                    TbxLoopSendTime.ReadOnly = false;
                    TimerLoopSend.Stop();
                }
            }
            else
            {
                if (checkBoxLoopSend.Checked == true)
                {
                    checkBoxLoopSend.Checked = false;
                    MessageBox.Show("串口未打开");
                }
            }
        }

        //过滤输入时间值
        private void TbxLoopSendTime_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar < '0' || e.KeyChar > '9')
            {
                if (e.KeyChar != '\b')
                    e.Handled = true;   //不处理
            }
            else
            {
                if (TbxLoopSendTime.TextLength > 5)
                    e.Handled = true;   //不处理
            }
        }


        #endregion

        #region 文本保存、清除、悬停
        private void richText_sp_MouseWheel(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            //上滚轮 则停止滚动
            if (e.Delta > 0)
            {
                CheckBoxShowTime.Focus();
            }
        }

        private void BtnSpTextClear_Click(object sender, EventArgs e)
        {
            richText_sp.Clear();
            ClearTxRxState();

            richText_sp.ScrollBars = RichTextBoxScrollBars.None;
            richText_sp.ScrollBars = RichTextBoxScrollBars.Vertical;
        }

        private void BtnClearSingleSend_Click(object sender, EventArgs e)
        {
            TbxSingleSend.Clear();
        }

        private void BtnSpTextSave_Click(object sender, EventArgs e)
        {
            if (richText_sp.Text == string.Empty)
            {
                MessageBox.Show("接收区为空，不保存！");
            }
            else
            {
                SaveFileDialog saveFile = new SaveFileDialog();
                saveFile.Filter = "TXT文本|*.txt";
                if (saveFile.ShowDialog() == DialogResult.OK)
                {
                    System.IO.File.AppendAllText(saveFile.FileName, "\r\n****** text save time: " + DateTime.Now.ToString() + " ******\r\n");
                    System.IO.File.AppendAllText(saveFile.FileName, richText_sp.Text);
                    MessageBox.Show("保存成功！");
                }
            }
        }

        #endregion

        #region 状态栏
        private void UpdateTxRxState()
        {
            LabelTxCnt.Text = "T:" + VboxSerialPort.TxByte.ToString();
            LabelRxCnt.Text = "R:" + VboxSerialPort.RxByte.ToString();
        }
        private void ClearTxRxState()
        {
            VboxSerialPort.TxByte = 0;
            VboxSerialPort.RxByte = 0;
            UpdateTxRxState();
        }

        #endregion

        #region 扩展功能
        private void BtnOpenFile_Click(object sender, EventArgs e)
        {
            //点击弹出对话框
            OpenFileDialog ofd = new OpenFileDialog();
            //设置对话框的标题
            ofd.Title = "请选择要打开的文本文件哟亲 O(∩_∩)O~";
            //设置对话框可以多选
            ofd.Multiselect = true;
            //设置对话框的初始目录
            ofd.InitialDirectory = @"C:\Users\SpringRain\Desktop";

            //设置对话框的文件类型
            ofd.Filter = "文本文件|*.txt|文本文件|*.bin|所有文件|*.*";

            //展示对话框
            if (ofd.ShowDialog() != DialogResult.OK)
                return;

            //获得在打开对话框中选中文件的路径
            selectPath = ofd.FileName;
            if (selectPath == null)
                return;

            TbxFilePath.Text = selectPath;
        }

        private void BtnSavePath_Click(object sender, EventArgs e)
        {
            //打开保存文件对话框
            SaveFileDialog sfd = new SaveFileDialog();

            sfd.OverwritePrompt = true;//询问是否覆盖
            sfd.Filter = "*.log|*.log";
            sfd.DefaultExt = "log";//缺省默认后缀名

            if (sfd.ShowDialog() != DialogResult.OK)
                return;

            savePath = sfd.FileName;
            if (savePath == null)
                return;

            TbxFilePath.Text = savePath;
        }

        private void BtnSendFile_Click(object sender, EventArgs e)
        {
            int fileSize = 0;
            byte[] fileBuffer;

            if (selectPath == null)
            {
                MessageBox.Show("请选择文件");
                return;
            }

            CheckBoxNewLine.Checked = false;

            using (FileStream fsRead = new FileStream(selectPath, FileMode.OpenOrCreate, FileAccess.Read))
            {
                fileBuffer = new byte[1024 * 1024 * 5];
                //实际读取到的字节数
                fileSize = fsRead.Read(fileBuffer, 0, fileBuffer.Length);

                TbxSingleSend.Text = Encoding.Default.GetString(fileBuffer, 0, fileSize);
            }

            if (fileSize % 512 == 0)
            {
                progressBar1.Maximum = (int)fileSize / 512;
            }
            else
            {
                progressBar1.Maximum = (int)(fileSize / 512 + 1);
            }
            progressBar1.Minimum = 0;

            int FrameNum = 0;
            int send_len = 0;
            byte[] tmpbyte = new byte[1200];

            if (serial != null)
            {
                progressBar1.Visible = true;
                for (int i = 0; i < progressBar1.Maximum; i++)
                {
                    progressBar1.Value = ++FrameNum;
                    if ((fileSize - 512 * (FrameNum - 1)) / 512 != 0)
                    {
                        send_len = 512;
                    }
                    else
                    {
                        send_len = (int)(fileSize % 512);
                    }

                    for (int j = 0; j < send_len; j++)
                    {
                        tmpbyte[0 + j] = fileBuffer[j + (FrameNum - 1) * 512];
                    }
                    serial.Write(tmpbyte, 0, send_len);

                    VboxSerialPort.TxByte += send_len;
                    UpdateTxRxState();
                }
                MessageBox.Show("发送完毕");
                progressBar1.Visible = false;
            }
            else
            {
                MessageBox.Show("请打开串口");
            }
        }

        private void CheckBoxSaveToFile_CheckedChanged(object sender, EventArgs e)
        {
            if ((savePath == null) || (!savePath.Contains(".log")))
            {
                if (CheckBoxSaveToFile.Checked == true)
                {
                    MessageBox.Show("文件格式不正确，请使用存储按钮选择/创建.log文件");
                    CheckBoxSaveToFile.Checked = false;
                }
                return;
            }

            if (serial != null)
            {
                string time = DateTime.Now.ToLongTimeString().ToString();

                richText_sp.AppendText("\r\n[" + time + "] ");

                if (CheckBoxSaveToFile.Checked == true)
                {
                    label_info.Text= "正在保存数据到 "+ savePath.ToString();
                    richText_sp.AppendText("开始保存数据到：" + savePath.ToString() + "\r\n");
                }
                else
                {
                    label_info.Text = "";
                    richText_sp.AppendText("保存数据结束\r\n");
                }
            }
            else
            {
                MessageBox.Show("请打开串口");
                CheckBoxSaveToFile.Checked = false;
            }
        }

        void SaveToFileOrTextbox(string text)
        {
            if (CheckBoxSaveToFile.Checked == true)
            {
                if (savePath != null)
                {
                    //打开一个文件（文件不存在就创建）并追加内容然后关闭文件
                    System.IO.File.AppendAllText(savePath, text);
                }
                richText_sp.AppendText(text);
            }
            else
            {
                richText_sp.AppendText(text);
            }
        }

        private void Btn17691_Click(object sender, EventArgs e)
        {
            string LineData = string.Empty;

            if (selectPath == null)
            {
                MessageBox.Show("请选择文件");
                return;
            }

            //获取文件信息 读取文件内容
            FileInfo fi = new FileInfo(selectPath);
            StreamReader reader = new StreamReader(selectPath, Encoding.Default);

            //初始化解析需要用到的资源
            GB17691.gb17691_init();

            //初始化进度条
            progressBar1.Maximum = (int)fi.Length;
            progressBar1.Minimum = 0;
            progressBar1.Visible = true;

            //循环按行读取数据并解析
            try
            {
                while (true)
                {
                    LineData = reader.ReadLine();
                    progressBar1.Value += LineData.Length;
                    GB17691.gb17691_analysis(LineData);
                }
            }
            catch
            {
                progressBar1.Value = progressBar1.Maximum;
                // 读取不到数据抛出异常
                reader.Close();
            }
            progressBar1.Visible = false;

            //释放处理相关资源
            GB17691.gb17691_finish(selectPath);
            MessageBox.Show("解析完成");
        }

        #endregion


        private void btnHexSum_Click(object sender, EventArgs e)
        {
            char[] src = txbInput.Text.ToCharArray();
            byte[] p = new byte[src.Length];
            byte[] des = new byte[2048];
            UInt32 sum = 0;

            for (int i = 0; i < src.Length; i++)
            {
                p[i] = Convert.ToByte(src[i]);
            }

            UInt32 hexlen = tools.Ascii2Byte(des, p, (UInt16)(src.Length));

            for (int i = 0; i < hexlen; i++)
            {
                sum += des[i];
            }
            txbOutput.AppendText("16进制结果："+ sum.ToString ("X2")+"\r\n");
        }

        private void btnCRC16_1432_Click(object sender, EventArgs e)
        {
            char[] src = txbInput.Text.ToCharArray();
            byte[] p = new byte[src.Length];
            UInt32 crc = 0;
            byte[] des = new byte[2048];

            for (int i = 0; i < src.Length; i++)
            {
                p[i] = Convert.ToByte(src[i]);
            }

            UInt32 hexlen = tools.Ascii2Byte(des, p, (UInt16)(src.Length));

            crc = tools.CRC16Caculate(des, (UInt16)hexlen);

            txbOutput.AppendText("16进制数据 CRC16结果：" + crc.ToString("X2") + "\r\n");
        }

        #region 16进制数据接收 断行
        private void CheckBoxHexShow_CheckedChanged(object sender, EventArgs e)
        {
            if(CheckBoxHexShow.Checked == true)
            {
                VboxSerialPort.HexRecvFlag = true;
                TimerHexRecv.Interval = 1;
            }
            else
            {
                VboxSerialPort.HexRecvFlag = false;
                TimerHexRecv.Stop();
            }
        }

        private void TimerHexRecv_Tick(object sender, EventArgs e)
        {
            if (TimerHexRecvCount++ > 1)
            {
                TimerHexRecvCount = 0;
                richText_sp.AppendText("\r\n");
                TimerHexRecv.Stop();
            }
                
        }
        #endregion

        #region msh手动输入
        private void richText_sp_KeyDown(object sender, KeyEventArgs e)
        {
            Msh.MshKeyDown(sender,e);
        }
        
        private void CheckBoxInputSelf_CheckedChanged(object sender, EventArgs e)
        {
            if(CheckBoxInputSelf.Checked == true)
            {
                Msh.MshSerial = serial;
            }
        }
        #endregion

        #region 历史发送记录
        private void CbxSendHistory_SelectedIndexChanged(object sender, EventArgs e)
        {
            TbxSingleSend.Text = cbxSendHistory.Text;
        }

        private void CbxSendHistory_Click(object sender, EventArgs e)
        {
            if (File.Exists(send_history_path) == false)
                return;

            cbxSendHistory.Items.Clear();
            string[] history = File.ReadAllLines(send_history_path);
            for (int i = history.Length - 1; i >= 0; i--)
                cbxSendHistory.Items.Add(history[i]);
        }
        #endregion

        private void RichText_sp_TextChanged(object sender, EventArgs e)
        {
            //实时保存数据情况下 窗口显示数据又最大长度限制
            if (CheckBoxSaveToFile.Checked == true)
            {
                if (richText_sp.Text.Length > 100000)
                {
                    richText_sp.Text = richText_sp.Text.Remove(0, 30000);
                }
            }
        }

        private void CbxSpName_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (CbxSpName.Text == "TCP/IP...")
            {
                label1.Text = "功能";
                label2.Text = "模式";
                label3.Text = "服务器IP";
                label4.Text = "服务器端口";
                label5.Text = "客户端信息";
                
                CbxBaudRate.Text = "";
                CbxStopBit.Text = "";
                CbxDataBit.Text = "";
                CbxCheckBit.Text = "";

                CbxBaudRate.Items.Clear();
                CbxStopBit.Items.Clear();
                CbxDataBit.Items.Clear();
                CbxCheckBit.Items.Clear();

                CbxBaudRate.Items.Add("tcp_server");
                CbxBaudRate.Items.Add("tcp_client");
                // CbxBaudRate.Items.Add("tcp_server");
                CbxStopBit.DropDownStyle = ComboBoxStyle.DropDown;
                CbxDataBit.DropDownStyle = ComboBoxStyle.DropDown;
                CbxCheckBit.DropDownStyle = ComboBoxStyle.DropDown;

            }
            else
            {
                label1.Text = "串口";
                label2.Text = "波特率";
                label3.Text = "停止位";
                label4.Text = "数据位";
                label5.Text = "奇偶检验";

                CbxBaudRate.DropDownStyle = ComboBoxStyle.DropDownList;
                CbxStopBit.DropDownStyle = ComboBoxStyle.DropDownList;
                CbxDataBit.DropDownStyle = ComboBoxStyle.DropDownList;
                CbxCheckBit.DropDownStyle = ComboBoxStyle.DropDownList;

                VboxSerialPort.SetBauRateValues(CbxBaudRate);
                VboxSerialPort.SetDataBitValues(CbxDataBit);
                VboxSerialPort.SetStopBitValues(CbxStopBit);
                VboxSerialPort.SetParityValues(CbxCheckBit);

                if (CbxBaudRate.Text == "")
                    CbxBaudRate.Text = "115200";
                if (CbxStopBit.Text == "")
                    CbxStopBit.Text = "1";
                if (CbxDataBit.Text == "")
                    CbxDataBit.Text = "8";
                if (CbxCheckBit.Text == "")
                    CbxCheckBit.Text = "无";
            }
        }
    }
}
